package common

import (
	"context"
	"database/sql"
	"time"
)

// KwdbColumn represents a column (field) definition in a kwdb database table
type KwdbColumn struct {
	// Name is the column name
	Name string `json:"name"`

	// Position is the position of the column in the table
	Position int `json:"position"`

	// Type is the data type of the column, such as "INT", "VARCHAR", "TEXT", etc.
	Type string `json:"type"`

	// Length is the column length, applicable to types like VARCHAR(255).
	// Default is 0, indicating no limit or using default value
	Length sql.NullString `json:"length"`

	// Precision is the total number of digits, applicable to DECIMAL or NUMERIC types
	Precision int `json:"precision"`

	// Scale is the number of digits after the decimal point, applicable to DECIMAL or NUMERIC types
	Scale sql.NullString `json:"scale"`

	// Nullable indicates whether the column allows NULL values, default is true
	Nullable sql.NullString `json:"nullable"`

	// DefaultValue is the default value for the column, can be string, number, etc., parsed according to Type
	DefaultValue sql.NullString `json:"default_value"`

	// PrimaryKey indicates whether this column is a primary key
	PrimaryKey sql.NullString `json:"primary_key"`

	// Unique indicates whether this column has a unique constraint
	Unique sql.NullString `json:"unique"`

	// Comment is the description or comment for the column
	Comment sql.NullString `json:"comment,omitempty"`

	// AutoIncrement indicates whether this column is auto-incrementing (typically used for integer primary keys)
	AutoIncrement sql.NullString `json:"auto_increment"`

	// Charset is the character set for string type columns
	Charset sql.NullString `json:"charset,omitempty"`

	// Collation is the collation rule for string type columns
	Collation sql.NullString `json:"collation,omitempty"`

	// For timeseries table
	Tag string `json:"tag"`
}

// IndexInfo 表示数据库索引的信息
type IndexInfo struct {
	// 索引名称
	Name string `json:"name"`

	// 索引类型（如：PRIMARY, UNIQUE, INDEX, FULLTEXT等）
	Type string `json:"type"`

	// 索引涉及的列信息
	Columns []IndexColumn `json:"columns"`

	// 是否唯一索引
	IsUnique bool `json:"is_unique"`

	// 是否为主键索引
	IsPrimary bool `json:"is_primary"`
}

// IndexColumn 表示索引中的列信息
type IndexColumn struct {
	// 列名
	Name string `json:"name"`

	// 列在索引中的顺序位置
	Position int `json:"position"`

	// 排序顺序，ASC 或 DESC
	SortOrder string `json:"sort_order"`
}

// TableDefinition 表示表的完整定义信息
type TableDefinition struct {
	// 数据库名称
	DatabaseName string `json:"database_name"`

	// 模式名称（对于支持模式的数据库如PostgreSQL）
	SchemaName string `json:"schema_name"`

	// 表名称
	TableName string `json:"table_name"`

	// 表注释
	Comment sql.NullString `json:"comment"`

	// 表的列定义
	Columns []KwdbColumn `json:"columns"`

	// 表的索引信息
	Indexes []IndexInfo `json:"indexes"`

	// 表的其他属性，时序表的keep属性存于此
	Properties map[string]interface{} `json:"properties,omitempty"`
}

type DBConnectionInfo struct {
	Ip           string
	Port         int
	User         string
	Password     string
	Dbtype       string
	SSL          bool
	Compress     bool
	Method       int //
	DatabaseName string
	InstanceName string
}
type TableStatistics struct {
	DBName      string    `json:"db_name"`
	SchemaName  string    `json:"schema_name"`
	TableName   string    `json:"table_name"`
	Count       int64     `json:"count"`
	StartTime   time.Time `json:"start_time"`
	EndTime     time.Time `json:"end_time"`
	Error       string    `json:"error"`
	AddedRows   int64     `json:"added_rows"`
	UpdatedRows int64     `json:"updated_rows"`
	DeletedRows int64     `json:"deleted_rows"`
}
type TaskStattistics struct {
	TaskName   string            `json:"task_name"`
	TaskType   string            `json:"task_type"` //migrate or verify
	StartTime  time.Time         `json:"start_time"`
	EndTime    time.Time         `json:"end_time"`
	Status     string            `json:"status"`
	Error      string            `json:"error"`
	TableStats []TableStatistics `json:"table_stattistics"`
}

// MigrateTask 定义数据库同步任务的结构
type MigrateTask struct {
	// 任务名称
	Name string `json:"name"`

	// 任务描述
	Description string `json:"description,omitempty"`

	// 源数据库配置列表
	Source DatabaseInfo `json:"source"`

	// 目标数据库配置列表
	Target DatabaseInfo `json:"target"`
	// 任务类型，可以是迁移，校对数据库，或者两者都做
	Type string `json:"type"` //migrate,verify,all

	// 同步模式，可以是全量同步，或者增量同步默认全量
	Mode string `json:"mode"` //full,incremental
}
type DatabaseInfo struct {
	//数据库连接信息
	DBCon     DBConnectionInfo `json:"dbcon"`
	Databases []DatabaseConfig `json:"databases"`
}

// DatabaseConfig 数据库配置信息
type DatabaseConfig struct {
	// 数据库名称
	Name string `json:"name"`

	// 模式名称（对于支持模式的数据库如PostgreSQL）
	Schema string `json:"schema,omitempty"`

	// 包含的表列表
	Includes []TableConfig `json:"includes,omitempty"`

	// 排除的表列表
	Excludes []TableConfig `json:"excludes,omitempty"`
	IsSeries bool          `json:"isseries"`
}

// TableConfig 表配置信息
type TableConfig struct {
	// 表名称
	Name string `json:"name"`

	// 自定义查询条件
	Condition string `json:"condition,omitempty"`

	// 包含的字段列表
	Includes []string `json:"includes,omitempty"`

	// 排除的字段列表
	Excludes []string `json:"excludes,omitempty"`

	//是否使用现有表，默认为false，如果为false，则会自动创建表
	UseExist bool `json:"use_exist"`
}

// bin log 信息
type ReplicateStartPos struct {
	Name     string
	Position uint64
	ServerId int64
	Pos      interface{}
}

// ReplicateHandlerInterface
type ReplicateHandlerInterface interface {
	ReplicateRecords(dbName, schemaName, tableName string, columns []KwdbColumn, values [][]interface{}, replicateType string) (uint64, error)
	GetTableColumn(databaseName, schemaName, tableName string) ([]KwdbColumn, error)
}

// RowsInterface 定义与 *sql.Rows 兼容的接口
type RowsInterface interface {
	Next() bool
	Close() error
	Scan(dest ...interface{}) error
	Err() error
	Columns() ([]string, error)
}

// SQLRowsWrapper 包装标准的 *sql.Rows 以实现 RowsInterface
type SQLRowsWrapper struct {
	rows *sql.Rows
}

func (w *SQLRowsWrapper) Next() bool {
	return w.rows.Next()
}

func (w *SQLRowsWrapper) Scan(dest ...interface{}) error {
	return w.rows.Scan(dest...)
}

func (w *SQLRowsWrapper) Columns() ([]string, error) {
	return w.rows.Columns()
}

func (w *SQLRowsWrapper) Close() error {
	return w.rows.Close()
}

func (w *SQLRowsWrapper) Err() error {
	return w.rows.Err()
}

// WrapSQLRows 为 *sql.Rows 创建包装器的便捷函数
func WrapSQLRows(rows *sql.Rows) RowsInterface {
	return &SQLRowsWrapper{rows: rows}
}
func IsStopped(ctx context.Context) bool {

	if ctx == nil {
		return false
	}
	select {
	case <-ctx.Done():
		return true
	default:
		return false
	}

}

// DataType 表示数据类型定义
type DataType struct {
	Name        string   // 名称
	Aliases     []string // 别名
	Description string   // 说明
}

// DataTypesStruct 包含所有数据类型的结构体
type DataTypesStruct struct {
	INT2        DataType
	INT4        DataType
	INT8        DataType
	FLOAT8      DataType
	FLOAT4      DataType
	DECIMAL     DataType
	BOOL        DataType
	BIT         DataType
	VARBIT      DataType
	BYTES       DataType
	VARBYTES    DataType
	CHAR        DataType
	NCHAR       DataType
	VARCHAR     DataType
	NVARCHAR    DataType
	BLOB        DataType
	CLOB        DataType
	TIMESTAMP   DataType
	TIMESTAMPTZ DataType
	DATE        DataType
	TIME        DataType
	INTERVAL    DataType
	JSONB       DataType
	INET        DataType
	TEXT        DataType
	UUID        DataType
}

// DataTypes 全局数据类型实例
var DataTypes = DataTypesStruct{
	INT2: DataType{
		Name:        "INT2",
		Aliases:     []string{"SMALLINT"},
		Description: "2 字节",
	},
	INT4: DataType{
		Name:        "INT4",
		Aliases:     []string{"INT", "INTEGER"},
		Description: "4 字节",
	},
	INT8: DataType{
		Name:        "INT8",
		Aliases:     []string{"INT64", "BIGINT"},
		Description: "8 字节",
	},
	FLOAT8: DataType{
		Name:        "FLOAT8",
		Aliases:     []string{"DOUBLE", "DOUBLE PRECISION", "FLOAT"},
		Description: "8 字节，最大精度为 17 位十进制小数",
	},
	FLOAT4: DataType{
		Name:        "FLOAT4",
		Aliases:     []string{"REAL"},
		Description: "4 字节",
	},
	DECIMAL: DataType{
		Name:        "DECIMAL",
		Aliases:     []string{"DEC", "NUMERIC"},
		Description: "9 ~ 64K 字节，用于存储精确的定点数，适用于需要保留精确精度的数据",
	},
	BOOL: DataType{
		Name:        "BOOL",
		Aliases:     []string{"BOOLEAN"},
		Description: "1 字节",
	},
	BIT: DataType{
		Name:        "BIT",
		Aliases:     []string{"BIT"},
		Description: "1字节，可以跟长度，比如BIT (2)",
	},
	VARBIT: DataType{
		Name:        "VARBIT",
		Aliases:     []string{"VARBIT"},
		Description: "无最大值限制的可变长度，用于存储长度可变的二进制位数组，可以跟长度，比如VARBIT(123)",
	},
	BYTES: DataType{
		Name:        "BYTES",
		Aliases:     []string{"BYTEA"},
		Description: "0 ~ 1023 字节，存储指定长度的二进制字符串",
	},
	VARBYTES: DataType{
		Name:        "VARBYTES",
		Aliases:     []string{"VARBYTES"},
		Description: "0 ~ 64K 字节，可变长的二进制字符类型，以实际的二进制字符串长度存储数据",
	},
	CHAR: DataType{
		Name:        "CHAR",
		Aliases:     []string{"CHARACTER"},
		Description: "一种定长字符类型，其存储长度由指定长度确定",
	},
	NCHAR: DataType{
		Name:        "NCHAR",
		Aliases:     []string{"NCHAR"},
		Description: "定长字符类型，其存储长度由指定长度确定",
	},
	VARCHAR: DataType{
		Name:        "VARCHAR",
		Aliases:     []string{"VARCHAR"},
		Description: "可变长字符类型，存储长度由数据的实际长度确定",
	},
	NVARCHAR: DataType{
		Name:        "NVARCHAR",
		Aliases:     []string{"NVARCHAR"},
		Description: "可变长字符类型，其存储长度由实际字符的长度确定",
	},
	BLOB: DataType{
		Name:        "BLOB",
		Aliases:     []string{"BLOB"},
		Description: "存储非文本的字节流数据（如程序、图象、影音等）",
	},
	CLOB: DataType{
		Name:        "CLOB",
		Aliases:     []string{"CLOB"},
		Description: "与字符集相关，用以存储文本型的数据（如历史档案、大部头著作等）",
	},
	TIMESTAMP: DataType{
		Name:        "TIMESTAMP",
		Aliases:     []string{"TIMESTAMP WITHOUT TIME ZONE"},
		Description: "以协调世界时（Coodinated Universal Time，UTC）格式存储日期和时间。",
	},
	TIMESTAMPTZ: DataType{
		Name:        "TIMESTAMPTZ",
		Aliases:     []string{"TIMESTAMP WITH TIME ZONE"},
		Description: "将时间戳数值从 UTC 时区转换为客户端会话时区。",
	},
	DATE: DataType{
		Name:        "DATE",
		Aliases:     []string{"DATE"},
		Description: "DATE 类型的存储最多占用 16 个字节",
	},
	TIME: DataType{
		Name:        "TIME",
		Aliases:     []string{"TIME WITHOUT TIME ZONE"},
		Description: "TIME 类型的小数部分可选，四舍五入到微秒级别（即小数点后的六位数）",
	},
	INTERVAL: DataType{
		Name:        "INTERVAL",
		Aliases:     []string{"INTERVAL"},
		Description: "用于存储表示时间跨度的值，支持的最大宽度为 24 个字节",
	},
	JSONB: DataType{
		Name:        "JSONB",
		Aliases:     []string{"JSON"},
		Description: "用于以二进制形式存储 JSON 数据",
	},
	INET: DataType{
		Name:        "INET",
		Aliases:     []string{"INET"},
		Description: "用于存储 IPv4 或 IPv6 地址",
	},
	TEXT: DataType{
		Name:        "TEXT",
		Aliases:     []string{"TEXT"},
		Description: "用于存储文本数据",
	},
	UUID: DataType{
		Name:        "UUID",
		Aliases:     []string{"UUID"},
		Description: "用于存储 128 位的数值",
	},
}

// GetFullTableName 获取完整的表名（包括数据库和模式）
func GetFullTableName(dbName, schemaName, tableName string) string {
	table := tableName
	if schemaName != "" {
		table = schemaName + "." + table
	}
	if dbName != "" {
		table = dbName + "." + table
	}
	return table
}
